package com.wanwu.channel.server.process;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.wanwu.channel.common.enums.*;
import com.wanwu.channel.common.exception.SystemException;
import com.wanwu.channel.common.util.DateUtils;
import com.wanwu.channel.common.util.TrueFalse;
import com.wanwu.channel.core.ChannelPayService;
import com.wanwu.channel.dao.entity.ChannelPayEntity;
import com.wanwu.channel.dao.entity.ChannelRefundEntity;
import com.wanwu.channel.remote.wxpay.config.WeixinGlobalConfig;
import com.wanwu.channel.remote.wxpay.util.WXPayUtil;
import com.wanwu.channel.server.model.NotifyResponse;
import com.wanwu.channel.core.tool.AlarmPoolUtil;
import com.wanwu.monitor.api.util.vo.AlarmMsgVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * 微信回调通知
 */
@Component
public class WexinNotifyProcess {

    private static final Logger logger = LoggerFactory.getLogger(WexinNotifyProcess.class);

    @Resource
    private ChannelPayService channelPayService;





    @Autowired
    private WeixinGlobalConfig weixinGlobalConfig;

    @Resource
    private AlarmPoolUtil alarmPoolUtil;


    /**
     * 支付回调
     * @param wechatNotifyStr
     * @return
     */
    public NotifyResponse weixinPayNotify(String wechatNotifyStr,String bizCode) {
        //判断返回报文里面的return_code，如果不是SUCCESS说明微信内部出现问题，直接报警
        Map<String, String> notifyParam = WXPayUtil.xmlToMap(wechatNotifyStr);
        if (!TrueFalse.UPPER_SUCCESS.equals(notifyParam.get("return_code"))) {
            //报警通知稍后再加
            //DingUtil.sendDingAtPeople(weixinGlobalConfig.getDingKey(), "微信失败的回调", JSON.toJSONString(notifyParam), null);
            alarmPoolUtil.addCommonAlarm(weixinGlobalConfig.getDingKey(), AlarmTypeEnum.WXNOTIFYFAIL, "渠道系统告警：微信失败的回调\n\n"+JSON.toJSONString(notifyParam));
            throw new SystemException(ExceptionEnum.E10010);
        }
        //查询订单是否存在
        ChannelPayEntity channelPayEntity = channelPayService.queryByBizOrderNoFMaster(notifyParam.get("out_trade_no"), bizCode);
        if (ObjectUtils.isEmpty(channelPayEntity)) {
            //报警通知稍后再加
            //DingUtil.sendDingAtPeople(weixinGlobalConfig.getDingKey(), "微信回调订单不存在", JSON.toJSONString(notifyParam), null);
            alarmPoolUtil.addCommonAlarm(weixinGlobalConfig.getDingKey(), AlarmTypeEnum.WXNOTIFYORDERNOTEXIST, "渠道系统告警：微信回调订单不存在\n\n"+JSON.toJSONString(notifyParam));
            throw new SystemException(ExceptionEnum.E10011);
        }
        //如果数据库订单状态是终态，则判断微信通知报文的状态跟数据库状态是否一致，一致则直接返回成功，不一致报警
        String weixinResultCode = notifyParam.get("result_code");
        if (!ChannelPayStatus.PROCESSING.getValue().equals(channelPayEntity.getPayStatus()) &&
                !ChannelPayStatus.NOTPAY.getValue().equals(channelPayEntity.getPayStatus())) {
            if ((TrueFalse.UPPER_SUCCESS.equals(weixinResultCode) && !ChannelPayStatus.SUCCESS.getValue().equals(channelPayEntity.getPayStatus())) ||
                    (TrueFalse.UPPER_FAIL.equals(weixinResultCode) && !ChannelPayStatus.FAIL.getValue().equals(channelPayEntity.getPayStatus()))) {
                //报警通知稍后再加
                //String msg = "渠道单号：" + channelPayEntity.getChannelNo() + "\n本地状态：" + channelPayEntity.getPayStatus() + "\n回调状态：" + weixinResultCode;
                //DingUtil.sendDingAtPeople(weixinGlobalConfig.getDingKey(), "微信回调状态与本地不一致", msg, null);
                AlarmMsgVo alarmMsgVo = new AlarmMsgVo.Builder().head("渠道系统告警：微信回调状态与本地不一致")
                        .field("渠道单号", channelPayEntity.getChannelNo())
                        .field("本地状态", channelPayEntity.getPayStatus())
                        .field("回调状态", weixinResultCode).build();
                alarmPoolUtil.addGatherAlarm(weixinGlobalConfig.getDingKey(), AlarmTypeEnum.WXNOTIFYSTATUSDIFF, alarmMsgVo);
                throw new SystemException(ExceptionEnum.E10012);
            } else {
                //直接返回微信回调处理成功
                return bulidSuccessResponse();
            }
        }
        //判断通知报文中总金额跟数据库是否一致，不一致报警
        int totalFee = Integer.parseInt(notifyParam.get("total_fee"));
        if (totalFee != channelPayEntity.getRmbAmount()) {
            //报警通知稍后再加
            //String msg = "渠道单号：" + channelPayEntity.getChannelNo() + "\n本地支付金额：" + channelPayEntity.getRmbAmount() + "\n回调支付金额：" + totalFee;
            //DingUtil.sendDingAtPeople(weixinGlobalConfig.getDingKey(), "微信支付回调订单金额与本地不一致", msg, null);
            AlarmMsgVo alarmMsgVo = new AlarmMsgVo.Builder().head("渠道系统告警：微信支付回调订单金额与本地不一致")
                    .field("渠道单号", channelPayEntity.getChannelNo())
                    .field("本地支付金额", channelPayEntity.getRmbAmount())
                    .field("回调支付金额", totalFee).build();
            alarmPoolUtil.addGatherAlarm(weixinGlobalConfig.getDingKey(), AlarmTypeEnum.WXPAYNOTIFYAMOUNTDIFF, alarmMsgVo);
            throw new SystemException(ExceptionEnum.E10013);
        }
        //处理回调结果
        channelPayEntity.setThirdOrderNo(notifyParam.get("transaction_id"));
        channelPayEntity.setTradeStatus(weixinResultCode);
        channelPayEntity.setNotifyData(JSON.toJSONString(notifyParam));
        if (TrueFalse.UPPER_SUCCESS.equals(weixinResultCode)) {
            //成功处理
            channelPayEntity.setPayStatus(ChannelPayStatus.SUCCESS.getValue());
            channelPayEntity.setErrorCode(ChannelPayStatus.SUCCESS.getDesc());
            channelPayEntity.setErrorMsg(ChannelPayStatus.SUCCESS.getDesc());
            channelPayEntity.setPayTime(DateUtils.formatDate(8, notifyParam.get("time_end")));
        } else {
            //失败处理
            channelPayEntity.setPayStatus(ChannelPayStatus.FAIL.getValue());
            channelPayEntity.setErrorCode(notifyParam.get("err_code"));
            channelPayEntity.setErrorMsg(notifyParam.get("err_code_des"));
        }

        //更新数据库
        ChannelPayEntity dao = channelPayService.queryByBizOrderNoFMaster(channelPayEntity.getBizOrderNo(),channelPayEntity.getBizCode());
        //只有数据库记录处于处理中状态以及从微信查到的状态不为处理中才更新
        if ((ChannelPayStatus.PROCESSING.getValue().equals(dao.getPayStatus()) ||
                !ChannelPayStatus.NOTPAY.getValue().equals(channelPayEntity.getPayStatus())) &&
                !ChannelPayStatus.PROCESSING.getValue().equals(channelPayEntity.getPayStatus())) {
            channelPayEntity.setUpdateTime(new Date());
            channelPayEntity.setNotifyNum(channelPayEntity.getNotifyNum() + 1);
            channelPayService.updateByChannelNo(channelPayEntity);
        }

        //回调支付系统
       // businessNotifyProcess.notifyToBusinessLine(channelPayEntity);
        return bulidSuccessResponse();
    }


    /**
     * 处理成功返回
     * @return
     */
    private NotifyResponse bulidSuccessResponse() {
        NotifyResponse response = new NotifyResponse();
        response.setReturnMsg("OK");
        response.setReturnCode("SUCCESS");
        return response;
    }

}
